package com.thinkit.bigdata.web.controller.bus;

import com.thinkit.bigdata.core.feature.orm.mybatis.Page;
import com.thinkit.bigdata.core.util.StringUtil;
import com.thinkit.bigdata.web.model.bus.BusTag;
import com.thinkit.bigdata.web.model.bus.BusTagCopyBean;
import com.thinkit.bigdata.web.model.bus.BusTagExample;
import com.thinkit.bigdata.web.model.config.SysArea;
import com.thinkit.bigdata.web.model.result.ConfigResult;
import com.thinkit.bigdata.web.model.result.Constants;
import com.thinkit.bigdata.web.model.result.HtmlResult;
import com.thinkit.bigdata.web.model.sec.TagTreeNode;
import com.thinkit.bigdata.web.model.sec.User;
import com.thinkit.bigdata.web.service.bus.BusTagService;
import com.thinkit.bigdata.web.service.config.AreaService;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.shiro.SecurityUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * 标签管理
 * Created by lihongli on 2018/10/12
 */

@Controller
@RequestMapping("busTag")
public class BusTagController {

    private static Logger logger = Logger.getLogger(BusTagController.class);

    private static final String AREAINFO = "areaInfo";

    @Resource
    private BusTagService busTagService;

    @Resource
    private AreaService areaService;

    /**
     * 分页查询业务标签信息
     *
     * @param request
     * @param sortOrder 排序方式
     * @param sortName  排序列名
     * @param pageNum   页码
     * @param pageSize  每页显示数量
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/busTagByPage", method = RequestMethod.POST)
    public Page<BusTag> busTagByPage(
            HttpServletRequest request,
            @RequestParam(value = "sortOrder") String sortOrder,
            @RequestParam(value = "sortName") String sortName,
            @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
            @RequestParam(value = "pageSize", defaultValue = "10") int pageSize) {
        String areaId = request.getParameter("areaId");   //左侧树选中的节点
        String tagId = request.getParameter("tagId");   //左侧树选中的节点
        String tagType = request.getParameter("tagType"); //标签标识
        String tagName = request.getParameter("tagName");   //搜索框输入的标签名称
        String logTxt = "【业务标签分页查询】";
        logger.info(logTxt + "查询条件: pageNum=" + pageNum);
        logger.info(logTxt + "查询条件: pageSize=" + pageSize);
        logger.info(logTxt + "查询条件: areaId=" + areaId);
        logger.info(logTxt + "查询条件: tagType=" + tagType);
        logger.info(logTxt + "查询条件: tagId=" + tagId);
        logger.info(logTxt + "查询条件: tagName=" + tagName);
        // 查询条件设置
        BusTagExample example = new BusTagExample();
        BusTagExample.Criteria criteria = example.createCriteria();
        if (StringUtil.isNotEmpty(areaId) && !"10000".equals(areaId)) {
            SysArea area = areaService.selectByPrimaryKey(Integer.valueOf(areaId));
            criteria.andProvincecodeEqualTo(area.getCode());
        }
//        if (StringUtil.isNotEmpty(tagId)) {
//            List<Long> list = selectSubTagId(Long.valueOf(tagId));
//            criteria.andIdIn(list);
//        }
        if (StringUtil.isNotEmpty(tagId)) {
            List<Long> list = selectSubTagId(Long.valueOf(tagId),tagType);
            if(list.size()==0){
            criteria.andIdEqualTo(Long.valueOf(tagId));

            }else{
                criteria.andIdIn(list);
            }
        }else{//点击话务小结/系统标签 仅查询1级分类
            criteria.andParentidEqualTo(0L);
        }
        if (StringUtil.isNotEmpty(tagType) && tagType.matches("\\d*")) {
            if ("0".equals(tagType)) {
                criteria.andTagtypeNotEqualTo(1);
            } else if ("1".equals(tagType)) {
                criteria.andTagtypeNotEqualTo(0);
            }
        }
        if (StringUtil.isNotEmpty(tagName)) {
            criteria.andNameLike("%" + tagName + "%");
        }
        // 限制可以查询出哪些省份
        SysArea area = (SysArea) request.getSession().getAttribute(AREAINFO);
        if (area != null) {
            // 不是集团用户的时候 限制只能查询自己省份设置的标签
            criteria.andProvincecodeEqualTo(area.getCode());
        }
        // 排序方式设置
        example.setOrderByClause(sortName + " " + sortOrder);
        // 分页设置
        Page<BusTag> page = new Page<>(pageNum, pageSize);
        busTagService.selectByExample(page, example);
        logger.info(logTxt + "共计查询到" + page.getResult().size() + "条业务标签信息");
        return page;
    }

    /**
     * 分页全查询业务标签信息
     *
     * @param request
     * @param sortOrder 排序方式
     * @param sortName  排序列名
     * @param pageNum   页码
     * @param pageSize  每页显示数量
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/busTagAllByPage", method = RequestMethod.POST)
    public Page<BusTag> busTagAllByPage(
            HttpServletRequest request,
            @RequestParam(value = "sortOrder") String sortOrder,
            @RequestParam(value = "sortName") String sortName,
            @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
            @RequestParam(value = "pageSize", defaultValue = "10") int pageSize) {
        String areaId = request.getParameter("areaId");   //左侧树选中的节点
        String tagType = request.getParameter("tagType"); //标签标识
        String tagName = request.getParameter("tagName");   //搜索框输入的标签名称
        String logTxt = "【业务标签分页全查询】";
        logger.info(logTxt + "查询条件: pageNum=" + pageNum);
        logger.info(logTxt + "查询条件: pageSize=" + pageSize);
        logger.info(logTxt + "查询条件: areaId=" + areaId);
        logger.info(logTxt + "查询条件: tagType=" + tagType);
        logger.info(logTxt + "查询条件: tagName=" + tagName);
        // 查询条件设置
        BusTagExample example = new BusTagExample();
        BusTagExample.Criteria criteria = example.createCriteria();
        if (StringUtil.isNotEmpty(areaId) && !"10000".equals(areaId)) {
            SysArea area = areaService.selectByPrimaryKey(Integer.valueOf(areaId));
            criteria.andProvincecodeEqualTo(area.getCode());
        }
        if (StringUtil.isNotEmpty(tagType) && tagType.matches("\\d*")) {
            if ("0".equals(tagType)) {
                criteria.andTagtypeNotEqualTo(1);
            } else if ("1".equals(tagType)) {
                criteria.andTagtypeNotEqualTo(0);
            }
        }
        if (StringUtil.isNotEmpty(tagName)) {
            criteria.andNameLike("%" + tagName + "%");
        }
        // 限制可以查询出哪些省份
        SysArea area = (SysArea) request.getSession().getAttribute(AREAINFO);
        if (area != null) {
            // 不是集团用户的时候 限制只能查询自己省份设置的标签
            criteria.andProvincecodeEqualTo(area.getCode());
        }
        // 排序方式设置
        example.setOrderByClause(sortName + " " + sortOrder);
        // 分页设置
        Page<BusTag> page = new Page<>(pageNum, pageSize);
        busTagService.selectByExample(page, example);
        logger.info(logTxt + "共计全查询到" + page.getResult().size() + "条业务标签信息");
        return page;
    }

    /**
     * 分页查询业务标签信息(仅返回叶子节点)
     *
     * @param request
     * @param sortOrder 排序方式
     * @param sortName  排序列名
     * @param pageNum   页码
     * @param pageSize  每页显示数量
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/busLeafTagByPage", method = RequestMethod.POST)
    public Page<BusTag> busLeafTagByPage(
            HttpServletRequest request,
            @RequestParam(value = "sortOrder") String sortOrder,
            @RequestParam(value = "sortName") String sortName,
            @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
            @RequestParam(value = "pageSize", defaultValue = "10") int pageSize) {
        String areaId = request.getParameter("areaId");   //左侧树选中的节点
        String tagId = request.getParameter("tagId");   //左侧树选中的节点
        String tagType = request.getParameter("tagType"); //标签标识
        String tagName = request.getParameter("tagName");   //搜索框输入的标签名称
        String logTxt = "【业务标签分页查询】";
        logger.info(logTxt + "查询条件: pageNum=" + pageNum);
        logger.info(logTxt + "查询条件: pageSize=" + pageSize);
        logger.info(logTxt + "查询条件: areaId=" + areaId);
        logger.info(logTxt + "查询条件: tagType=" + tagType);
        logger.info(logTxt + "查询条件: tagId=" + tagId);
        logger.info(logTxt + "查询条件: tagName=" + tagName);
        // 查询条件设置
        BusTagExample example = new BusTagExample();
        BusTagExample.Criteria criteria = example.createCriteria();
        if (StringUtil.isNotEmpty(areaId) && !"10000".equals(areaId)) {
            SysArea area = areaService.selectByPrimaryKey(Integer.valueOf(areaId));
            criteria.andProvincecodeEqualTo(area.getCode());
        }
        if (StringUtil.isNotEmpty(tagId)) {
            List<Long> list = selectleafSubTagId(Long.valueOf(tagId));
            if(list.size()==0){
                criteria.andIdEqualTo(Long.valueOf(tagId));
            }else{
                criteria.andIdIn(list);
            }
        }
        if (StringUtil.isNotEmpty(tagType) && tagType.matches("\\d*")) {
            if ("0".equals(tagType)) {
                criteria.andTagtypeNotEqualTo(1);
            } else if ("1".equals(tagType)) {
                criteria.andTagtypeNotEqualTo(0);
            }
        }
        if (StringUtil.isNotEmpty(tagName)) {
            criteria.andNameLike("%" + tagName + "%");
        }
        // 限制可以查询出哪些省份
        SysArea area = (SysArea) request.getSession().getAttribute(AREAINFO);
        if (area != null) {
            // 不是集团用户的时候 限制只能查询自己省份设置的标签
            criteria.andProvincecodeEqualTo(area.getCode());
        }
        // 排序方式设置
        example.setOrderByClause(sortName + " " + sortOrder);
        // 分页设置
        Page<BusTag> page = new Page<>(pageNum, pageSize);
        busTagService.selectLeafByExample(page, example);
        logger.info(logTxt + "共计查询到" + page.getResult().size() + "条业务标签信息");
        return page;
    }
    // 查询某个标签下所有标签--20191120修改为查询标签本身以及直接子标签
    private List<Long> selectSubTagId(Long tagId,String tagType){
        List<Long> tagIdList = new ArrayList<>();
        List<Long> searchList = new ArrayList<>();
        searchList.add(tagId);
        tagIdList.add(tagId);
        Iterator<Long> iterator;
        while((iterator = searchList.iterator()).hasNext()){
            Long next = iterator.next();
            iterator.remove();
            BusTagExample example = new BusTagExample();
            BusTagExample.Criteria criteria = example.createCriteria();
            criteria.andParentidEqualTo(next);
            if (StringUtil.isNotEmpty(tagType) && tagType.matches("\\d*")) {
                if ("0".equals(tagType)) {
                    criteria.andTagtypeNotEqualTo(1);
                } else if ("1".equals(tagType)) {
                    criteria.andTagtypeNotEqualTo(0);
                }
            }
            List<BusTag> busTagList = busTagService.selectByExample(example);
                for (BusTag busTag : busTagList) {
                    tagIdList.add(busTag.getId());
                    //searchList.add(busTag.getId());
                }
        }
       // tagIdList.add(tagId);
        return tagIdList;
    }
    // 查询某个标签下所有叶子标签
    private List<Long> selectleafSubTagId(Long tagId){
        List<Long> tagIdList = new ArrayList<>();
        List<Long> searchList = new ArrayList<>();
        searchList.add(tagId);
        Iterator<Long> iterator;
        while((iterator = searchList.iterator()).hasNext()){
            Long next = iterator.next();
            iterator.remove();
            BusTagExample example = new BusTagExample();
            example.createCriteria().andParentidEqualTo(next);
            List<BusTag> busTagList = busTagService.selectByExample(example);
            for (BusTag busTag : busTagList) {
                tagIdList.add(busTag.getId());
                searchList.add(busTag.getId());
            }
        }
        tagIdList.add(tagId);//增加本身、针对子节点为其他类型情景
        return tagIdList;
    }

    /**
     * 获取所有业务标签
     *
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping("/selectAllBusTag")
    public List<BusTag> selectAllBusTag(HttpServletRequest request, @RequestParam(value = "areaId", required = false) Integer areaId) {
        BusTagExample example = new BusTagExample();
        BusTagExample.Criteria criteria = example.createCriteria();
        if (areaId != null && areaId != 10000) {
            // 如果省份id不为空 只查询某个省份的标签
            SysArea area = areaService.selectByPrimaryKey(areaId);
            criteria.andProvincecodeEqualTo(area.getCode());
            return busTagService.selectByExample(example);
        }
        // 判断用户所属省份信息
        SysArea area = (SysArea) request.getSession().getAttribute(AREAINFO);
        if (area != null) {
            // 如果区域信息不为空 则取出某个省份的标签信息
            criteria.andProvincecodeEqualTo(area.getCode());
        }
        return busTagService.selectByExample(example);
    }

    /**
     * 构建页面上的标签树
     *
     * @param areaId 指定要加载的省份
     * @param tagType 指定要加载的标签标识分类
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/showTagTree", method = RequestMethod.GET)
    public TagTreeNode showTagTree(@RequestParam(required = false) Long areaId, @RequestParam(required = false) String tagType) {
        if (areaId == null) {
            // 如果没有传入省份信息 先判断用户身份 是不是集团人员 或是某个省份人员
            SysArea area = (SysArea) SecurityUtils.getSubject().getSession().getAttribute(AREAINFO);
            if (area != null) {
                areaId = area.getId().longValue();
            }
        }
        return busTagService.showTagTree(areaId, tagType);
    }

    /**
     * 导出所有标签信息到excel表
     *
     * @param request
     * @param response
     */
    @RequestMapping("/exportExcel")
    public void exportExcel(HttpServletRequest request, HttpServletResponse response) {
        logger.info("导出标签信息");
        // 查询条件
        String areaId = request.getParameter("areaId");   //左侧树选中的节点
        String tagId = request.getParameter("tagId");   //左侧树选中的节点
        String tagType = request.getParameter("tagType");   //左侧树选中的节点
        String tagName = request.getParameter("tagName");   //搜索框输入的标签名称
        String sortName = request.getParameter("sortName"); //排序列
        String sortOrder = request.getParameter("sortOrder"); //排序方式
        String selectId = request.getParameter("selectId"); //选中的id
        String isAll = request.getParameter("isAll");
        // 查询条件设置
        BusTagExample example = new BusTagExample();
        BusTagExample.Criteria criteria = example.createCriteria();
        if (StringUtil.isNotEmpty(areaId) && !"10000".equals(areaId)) {
            SysArea area = areaService.selectByPrimaryKey(Integer.valueOf(areaId));
            criteria.andProvincecodeEqualTo(area.getCode());
        }
        if (StringUtil.isNotEmpty(tagId)) {
            List<Long> list= selectSubTagId(Long.valueOf(tagId),tagType);
            if(list.size()==0){
                criteria.andIdEqualTo(Long.valueOf(tagId));
            }else{
                criteria.andIdIn(list);
            }
        }else if(isAll.isEmpty()){//点击话务小结/系统标签 仅查询1级分类
            criteria.andParentidEqualTo(0L);
        }
        if (StringUtil.isNotEmpty(tagType) && tagType.matches("\\d*")) {
            if ("1".equals(tagType)) {
                criteria.andTagtypeNotEqualTo(0);
            } else if ("0".equals(tagType)) {
                criteria.andTagtypeNotEqualTo(1);
            }
        }
        if (StringUtil.isNotEmpty(tagName)) {
            criteria.andNameLike("%" + tagName + "%");
        }
        if (StringUtil.isNotEmpty(selectId)) {
            List<Long> idList = new ArrayList<>();
            String[] idArray = selectId.split(",");
            for (String id : idArray) {
                idList.add(Long.valueOf(id));
            }
            criteria.andIdIn(idList);
        }
        // 限制可以查询出哪些省份
        SysArea area = (SysArea) request.getSession().getAttribute(AREAINFO);
        if (area != null) {
            // 不是集团用户的时候 限制只能查询自己省份设置的标签
            criteria.andProvincecodeEqualTo(area.getCode());
        }
        // 排序方式设置
        example.setOrderByClause(sortName + " " + sortOrder + ", id asc");
        List<BusTag> busTagList = busTagService.selectByExample(example);
        // 生成的excel的列名
        String[] columnNames = {"序号", "省份", "标签分类", "标签名称", "标签标识", "备注"};
        // 对应的实体类的属性名
        String[] filedNames = {"id", "provincename", "type", "name", "tagtypename", "note"};
        HSSFWorkbook hwb = fillDataIntoExcel(busTagList, columnNames, filedNames);
        try {
            //输出文件名
            String fileName = "业务标签信息表";
            // 创建文件输出流，准备输出电子表格
            response.reset();
            response.setContentType("application/msexcel"); // 定义输出类型
            response.setHeader("Content-disposition", "attachment;filename=" + new String(fileName.getBytes("GBK"), StandardCharsets.ISO_8859_1) + ".xls"); // 设定输出文件头
            OutputStream os = response.getOutputStream();
            hwb.write(os);
            os.close();
        } catch (IOException e) {
            logger.error("业务标签导出失败", e);
        }
    }

    /**
     * 填充数据到excel中
     *
     * @param busTagList  数据
     * @param columnNames 生成的excel的列名
     * @param filedNames  对应的实体类的属性名
     * @return
     */
    private HSSFWorkbook fillDataIntoExcel(List<BusTag> busTagList, String[] columnNames, String[] filedNames) {
        // 创建excel文档对象
        HSSFWorkbook hwb = new HSSFWorkbook();
        // 创建sheet对象 设置名称
        HSSFSheet sheet = hwb.createSheet("业务标签信息表");
        // 设置单元格样式
        HSSFCellStyle cellStyle = hwb.createCellStyle();
        cellStyle.setBorderLeft(BorderStyle.THIN);
        cellStyle.setBorderRight(BorderStyle.THIN);
        cellStyle.setBorderTop(BorderStyle.THIN);
        cellStyle.setBorderBottom(BorderStyle.THIN);
        // 创建标题行
        HSSFRow firstRow = sheet.createRow(0);
        for (int i = 0; i < columnNames.length; i++) {
            HSSFCell c = firstRow.createCell(i);
            c.setCellValue(columnNames[i]);
            c.setCellStyle(cellStyle);
        }
        // 循环写入用户信息
        for (int i = 0; i < busTagList.size(); i++) {
            HSSFRow row = sheet.createRow(i + 1);
            BusTag busTag = busTagList.get(i);
            for (int j = 0; j < filedNames.length; j++) {
                HSSFCell cell = row.createCell(j);
                if (j == 0) {
                    cell.setCellValue((double) i + 1);
                } else {
                    try {
                        // 通过反射获取属性 读取属性值
                        Field field = busTag.getClass().getDeclaredField(filedNames[j]);
                        field.setAccessible(true);
                        cell.setCellValue((String) field.get(busTag));
                    } catch (Exception e) {
                        cell.setCellValue("");
                    }
                }
                cell.setCellStyle(cellStyle);
            }
        }
        return hwb;
    }


    /**
     * 标签名称唯一性校验
     *
     * @param request
     * @param tagName
     * @param parentId 如果不传递该参数 则默认去查询省份下 第一级节点的标签
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/tagNameUniqueCheck", method = RequestMethod.POST)
    public Integer tagNameUniqueCheck(
            HttpServletRequest request,
            @RequestParam("tagName") String tagName,
            @RequestParam(value = "parentId", required = false) Long parentId) {
        String logTxt = "【标签名称唯一性校验】";
        logger.info(logTxt + "tagName = " + tagName + ", parentId = " + parentId);
        BusTagExample example = new BusTagExample();
        BusTagExample.Criteria criteria = example.createCriteria();
        if (parentId != null && parentId > 0) {
            // 正常省份下子级节点
            criteria.andParentidEqualTo(parentId);
        } else {
            // 如果parentId为空或者负数 说明为省份下 第一级节点 查询父节点为0的节点
            criteria.andParentidEqualTo(0l);
        }
        criteria.andNameEqualTo(tagName);
        Integer count = busTagService.countByExample(example);
        if (count > 0) {
            logger.info(logTxt + tagName + "已存在");
            return 1;
        } else {
            logger.info(logTxt + tagName + "不存在");
            return 0;
        }
    }

    /**
     * 新增标签树
     *
     * @param request
     * @param busTag
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/addBusTag", method = RequestMethod.POST)
    public ConfigResult addBusTag(HttpServletRequest request, BusTag busTag) {
        String logTxt = "【新增业务标签】";
        if (busTag.getProvinceid() == null) {
            return new ConfigResult(Constants.ERROR, "请选择标签所属省份");
        }
        SysArea area = areaService.selectByPrimaryKey(busTag.getProvinceid());
        // 取出省份code信息 放到bustag中
        busTag.setProvincecode(area.getCode());
        busTag.setContent(busTag.getName());
        Long parentid = busTag.getParentid();
        if (parentid != null && parentid > 0) {
            BusTag parentTag = busTagService.selectByPrimaryKey(parentid);
            busTag.setProvincecode(parentTag.getProvincecode());
            busTag.setContent(parentTag.getContent() + "-" + busTag.getName());
        } else {
            busTag.setParentid(0l);
        }
        logger.info(logTxt + busTag.toString());
        // 设置创建人信息
        User user = (User) SecurityUtils.getSubject().getSession().getAttribute(Constants.SESSION_USER_INFO);
        busTag.setCreateuserid(user.getId());
        busTag.setCreateusername(user.getUsername());
        try {
            // 写入业务标签
            Integer rowNum = busTagService.insertBusTag(busTag);
            if (rowNum > 0) {
                logger.info(logTxt + busTag.getName() + "添加成功");
                return new ConfigResult(Constants.SUCCESS, busTag.getName() + "添加成功");
            } else {
                logger.info(logTxt + busTag.getName() + "添加失败");
                return new ConfigResult(Constants.FAIL, busTag.getName() + "添加失败");
            }
        } catch (Exception e) {
            logger.error(logTxt + busTag.getName() + "添加错误", e);
            return new ConfigResult(Constants.ERROR, busTag.getName() + "添加错误");
        }
    }

    /**
     * 根据id获取业务标签
     *
     * @param request
     * @param id
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/getTagByPK", method = RequestMethod.POST)
    public BusTag getTagByPK(HttpServletRequest request, @RequestParam("id") Long id) {
        logger.info("获取id为" + id + "的业务标签信息");
        return busTagService.selectByPrimaryKey(id);
    }

    /**
     * 修改标签树
     *
     * @param request
     * @param busTag
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/updateBusTag", method = RequestMethod.POST)
    public ConfigResult updateBusTag(HttpServletRequest request, BusTag busTag) {
        String logTxt = "【业务标签修改】";
        logger.info(logTxt + busTag.toString());
        try {
            // 获取父标签的内容
            Long parentTagId = busTag.getParentid();
            if (parentTagId != null && parentTagId > 0) {
                BusTag source = busTagService.selectByPrimaryKey(parentTagId);
                // 给标签设置新的内容
                busTag.setContent(source.getContent() + "-" + busTag.getName());
            } else {
                busTag.setContent(busTag.getName());
            }
            // 写入数据库
            busTag.setLastupdatetime(new Date());
            User user = (User) SecurityUtils.getSubject().getSession().getAttribute(Constants.SESSION_USER_INFO);
            busTag.setLastupdateuserid(user.getId());
            Integer rowNum = busTagService.updateBusTag(busTag);
            if (rowNum > 0) {
                logger.info(logTxt + busTag.getName() + "修改成功");
                return new ConfigResult(Constants.SUCCESS, busTag.getName() + "修改成功");
            } else {
                logger.info(logTxt + busTag.getName() + "修改失败");
                return new ConfigResult(Constants.FAIL, busTag.getName() + "修改失败");
            }
        } catch (Exception e) {
            logger.error(logTxt + busTag.getName() + "修改错误", e);
            return new ConfigResult(Constants.ERROR, busTag.getName() + "修改错误");
        }
    }

    /**
     * 批量删除业务标签
     *
     * @param request
     * @param tagIdList
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/batchDeleteTag", method = RequestMethod.POST)
    public ConfigResult deleteBusTagBatch(HttpServletRequest request, @RequestParam("tagIdList") List<Long> tagIdList) {
        String logTxt = "【批量删除业务标签】";
        logger.info(logTxt + "id = " + StringUtils.join(tagIdList, ","));
        try {
            int rowNum = busTagService.deleteBusTag(tagIdList);
            if (rowNum > 0) {
                logger.info(logTxt + "批量删除成功");
                return new ConfigResult(Constants.SUCCESS, "批量删除成功");
            } else {
                logger.info(logTxt + "批量删除失败");
                return new ConfigResult(Constants.FAIL, "批量删除失败");
            }
        } catch (Exception e) {
            logger.error(logTxt + "批量删除错误", e);
            return new ConfigResult(Constants.ERROR, "批量删除错误");
        }
    }

    /**
     * 批量删除业务标签
     *
     * @param request
     * @param tagId
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/deleteTag", method = RequestMethod.POST)
    public ConfigResult deleteBusTag(HttpServletRequest request, @RequestParam("tagId") Long tagId) {
        String logTxt = "【删除业务标签】";
        logger.info(logTxt + "id = " + tagId);
        try {
            int rowNum = busTagService.deleteBusTag(tagId);
            if (rowNum > 0) {
                logger.info(logTxt + "删除成功");
                return new ConfigResult(Constants.SUCCESS, "删除成功");
            } else {
                logger.info(logTxt + "删除失败");
                return new ConfigResult(Constants.FAIL, "删除失败");
            }
        } catch (Exception e) {
            logger.error(logTxt + "删除错误", e);
            return new ConfigResult(Constants.ERROR, "删除错误");
        }
    }

    /**
     * 复制标签
     *
     * @param request
     * @param busTagCopyBean
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/copyBusTag", method = RequestMethod.POST)
    public ConfigResult copyBusTag(HttpServletRequest request, @RequestBody BusTagCopyBean busTagCopyBean) {
        String logTxt = "【复制标签】";
        Long parentId = busTagCopyBean.getParentId();
        if (parentId == null) {
            // 如果parentId为null  说明添加到根节点下 则设置parentId为0
            parentId = 0L;
        }
        logger.info(logTxt + "要复制到的省份provinceId = " + busTagCopyBean.getProvinceId());
        logger.info(logTxt + "分类parentId = " + parentId);
        // 获取目标省份信息
        SysArea area = areaService.selectByPrimaryKey(busTagCopyBean.getProvinceId());
        // 获取操作人信息
        User user = (User) SecurityUtils.getSubject().getSession().getAttribute(Constants.SESSION_USER_INFO);
        // 循环复制每一个标签
        List<BusTag> busTagList = busTagCopyBean.getBusTagList();
        int total = busTagList.size();
        int success = 0;
        for (BusTag busTag : busTagList) {
            // 先获取源标签信息
            BusTag source = busTagService.selectByPrimaryKey(busTag.getId());
            // 设置新的标签对象
            BusTag target = new BusTag();
            target.setParentid(parentId);// 分类
            target.setProvincecode(area.getCode());// 省份标识
            target.setName(busTag.getName());// 取页面重命名之后的标签名称
            target.setNote(source.getNote());// 备注
            if (parentId > 0) {
                // 获取parentId对应标签的内容
                BusTag parentTag = busTagService.selectByPrimaryKey(parentId);
                target.setContent(parentTag.getContent() + "-" + target.getName());
            }
            // 设置操作人信息
            target.setCreateusername(user.getUsername());
            target.setCreateuserid(user.getId());
            try {
                busTagService.insertBusTag(target);
                success++;
            } catch (Exception e) {
                logger.error(logTxt + busTag.getName() + "标签复制错误");
            }
        }
        if (success == 0) {
            return new ConfigResult(Constants.FAIL, "标签复制失败");
        } else {
            return new ConfigResult(Constants.SUCCESS, total + "个标签复制成功" + success + "个");
        }
    }

    /**
     * 批量导入标签
     *
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/importTags", method = RequestMethod.POST)
    public HtmlResult batchImportTag(MultipartHttpServletRequest request) {
        List<String[]> tagArrayList = null;
        MultipartFile file = request.getFile("uploadFile");
        // 所属省份
        String provinceCode = request.getParameter("provinceCode");
        try {
            tagArrayList = readFile(file);
        } catch (Exception e) {
            logger.error("文件读取过程中出现错误", e);
            return HtmlResult.failure("文件读取失败，请检查文件格式或内容");
        }
        if (tagArrayList.isEmpty()) {
            return HtmlResult.failure("文件内容为空");
        }
        // 写数据库
        String errorTagInfo = insertTags(tagArrayList, provinceCode);
        if (errorTagInfo.length() > 0) {
            errorTagInfo = errorTagInfo.substring(1);
            return HtmlResult.success(errorTagInfo + "标签所在行导入失败，请核查，其余标签均导入成功");
        }
        return HtmlResult.success("标签导入成功");
    }

    // 读取上传的文件
    private List<String[]> readFile(MultipartFile file) throws Exception {
        String filename = file.getOriginalFilename();
        int index = filename.lastIndexOf('.');
        if (filename.substring(index + 1).equals("txt")) {
            return readTxt(file);
        } else {
            return readExcel(file);
        }
    }

    // 读取excel
    private List<String[]> readExcel(MultipartFile file) throws Exception {
        List<String[]> tagArrayList = new ArrayList<>();
        try (Workbook workbook = WorkbookFactory.create(file.getInputStream())) {
            Sheet sheet = workbook.getSheetAt(0);
            int rowNum = sheet.getLastRowNum();
            // 从第二行开始读取 第一行为标题列
            for (int i = 1; i <= rowNum; i++) {
                // 对单元格的值进行处理
                String[] tagArray = spiltCellValueWithCheck(sheet.getRow(i).getCell(0));
                if (tagArray.length > 0) tagArrayList.add(tagArray);
            }
        }
        return tagArrayList;
    }

    // 读取txt
    private List<String[]> readTxt(MultipartFile file) throws Exception {
        List<String[]> tagArrayList = new ArrayList<>();
        BufferedReader br = new BufferedReader(new InputStreamReader(file.getInputStream(), StandardCharsets.UTF_8));
        String content = br.readLine();// 第一行内容丢弃
        while ((content = br.readLine()) != null) {
            String[] tagArray = spileToTagArray(content);
            if (tagArray.length > 0) tagArrayList.add(tagArray);
        }
        br.close();
        return tagArrayList;
    }

    // 处理单元格的值 同时对空值进行去除
    private String[] spiltCellValueWithCheck(Cell cell) {
        if (cell == null) {
            return new String[0];
        }
        // 强制单元格的值类型为String
        if (CellType.NUMERIC == cell.getCellType()) {
            cell.setCellType(CellType.STRING);
        }
        // 获取值 并处理
        return spileToTagArray(cell.getStringCellValue());
    }

    // 将读取到的值分割成数组
    private String[] spileToTagArray(String value) {
        // 对首尾去除空格
        String cellValue = value.trim();
        // 分割
        String[] tagArray = cellValue.split("-");
        StringBuilder sb = new StringBuilder();
        for (String tag : tagArray) {
            if (!StringUtil.isEmpty(tag))
                sb.append("-" + tag);
        }
        if (sb.toString().length() > 0)
            return sb.toString().substring(1).split("-");
        return new String[0];
    }

    // 将处理好的标签数组集合 写入到数据库
    private String insertTags(List<String[]> tagArrayList, String provinceCode) {
        // 设置创建人信息使用
        User user = (User) SecurityUtils.getSubject().getSession().getAttribute(Constants.SESSION_USER_INFO);
        String username = user.getUsername();
        Long userId = user.getId();
        // 存放tag-id的标签对象 减少数据库查询
        Map<String, Long> checkTagNameMap = new HashMap<>();
        // 保存父级标签的内容 减少数据库查询 设置content时使用
        Map<Long, BusTag> parentBusTagMap = new HashMap<>();
        // 写入数据库错误的标签
        StringBuilder errorTagInfo = new StringBuilder();
        for (String[] tagArray : tagArrayList) {
            // 每次循环读取前 设置parentId = 0
            Long parentid = 0L;
            StringBuilder checkTagName = new StringBuilder();
            for (int i = 0; i < tagArray.length; i++) {
                String tag = tagArray[i];
                checkTagName.append(tag + "-");
                // 标签名称在checkTagNameMap不存在 进行校验
                if (!checkTagNameMap.containsKey(checkTagName.toString())) {
                    BusTagExample example = new BusTagExample();
                    example.createCriteria().andParentidEqualTo(parentid).andNameEqualTo(tag).andProvincecodeEqualTo(provinceCode);
                    List<BusTag> busTagList = busTagService.selectByExample(example);
                    // 如果查询结果为空 说明数据库中不存在 则可以进行添加
                    if (busTagList.isEmpty()) {
                        BusTag busTag = new BusTag();
                        busTag.setParentid(parentid);
                        busTag.setProvincecode(provinceCode);
                        busTag.setName(tag);
                        String content = (parentid != 0) ? parentBusTagMap.get(parentid).getContent() + "-" + tag : tag;
                        busTag.setContent(content);
                        busTag.setCreatetime(new Date());
                        busTag.setCreateuserid(userId);
                        busTag.setCreateusername(username);
                        try {
                            busTagService.insertBusTag(busTag);
                            // 如果插入成功 将返回的id赋值给parentid 同时将该对象存入parentBusTagMap
                            parentid = busTag.getId();
                            parentBusTagMap.put(parentid, busTag);
                            // 将checkTagName与parentid也对应起来
                            checkTagNameMap.put(checkTagName.toString(), parentid);
                        } catch (Exception e) {
                            logger.error("插入过程中出现错误", e);
                            // 跳过该行数据的写入 同时把数据存入errorTagList中
                            errorTagInfo.append("," + tag);
                            break;
                        }
                    } else {
                        // 如果查询结果不为空 则把查询的对象存入parentBusTagMap
                        parentid = busTagList.get(0).getId();
                        parentBusTagMap.put(parentid, busTagList.get(0));
                        // 将checkTagName与parentid也对应起来
                        checkTagNameMap.put(checkTagName.toString(), parentid);
                    }
                } else {
                    // 更新parentid 保证标签的层级
                    parentid = checkTagNameMap.get(checkTagName.toString());
                }
            }
        }
        return errorTagInfo.toString();
    }
}
